import { itag } from "../itag/index.js";
import { createElements, define } from "../itag/util.js";
import type { IRequestFieldElement } from "./IFieldElement.js";
import type { CustomRequestFieldContext, CustomRequestFieldOption } from "./RequestOption.js";
import * as styles from "./styles.js";

function defaultCallback(_ctx: CustomRequestFieldContext): number[] {
    return [];
}

export class CustomRequestFieldElement extends HTMLElement implements IRequestFieldElement {
    #begin: number = 0;

    #cb: (ctx: CustomRequestFieldContext) => number[] = defaultCallback;

    readonly #elms = createElements({
        container: "div",
        inputs: "div",
        name: "div",
        range: "div",
    });

    readonly #inputs: HTMLInputElement[] = [];

    #result: number[] = [];

    constructor() {
        super();
        itag`
${this} .${styles.field}
    ${this.#elms.inputs}  .${styles.inputs}
    ${this.#elms.name}  .${styles.name}
    ${this.#elms.range} .${styles.range}
`;
    }

    get name(): string {
        return this.#elms.name.textContent ?? "";
    }

    get option(): CustomRequestFieldOption {
        return {
            name: this.#elms.name.textContent ?? "",
            kind: "custom",
            cb: this.#cb,
        };
    }

    set option(value: CustomRequestFieldOption) {
        this.#elms.name.textContent = value.name;
        this.#cb = value.cb ?? defaultCallback;
        this.#result = this.#cb({ lengths: {} });
        this.dispatchEvent(new Event("change"));
    }

    byteLength(): number {
        return this.#result.length;
    }

    data(): number[] {
        return this.#result;
    }

    setBegin(begin: number): void {
        this.#begin = begin;
        this.#elms.range.textContent = `${this.#begin}, ${this.#begin + this.#result.length}`;
    }

    update(ctx: CustomRequestFieldContext): void {
        const result = this.#result;
        this.#result = this.#cb(ctx);
        while (this.#inputs.length > this.#result.length) {
            this.#inputs.pop()?.remove();
        }
        for (let i = 0; i < this.#result.length; i++) {
            const value = this.#result[i]!;
            let input = this.#inputs[i];
            if (input === undefined) {
                input = document.createElement("input");
                input.readOnly = true;
                this.#elms.inputs.appendChild(input);
                this.#inputs.push(input);
            }
            input.value = value.toString(16).padStart(2, "0").toUpperCase();
        }

        if (result.length !== this.#result.length) {
            this.#elms.range.textContent = `${this.#begin}, ${this.#begin + this.#result.length}`;
            this.dispatchEvent(new Event("change"));
        }
    }
}

define(CustomRequestFieldElement);
